package com.orangelife.webservice.base;

import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.ws.rs.core.Response;

import com.orangelife.common.AbstractV2TransferService;
import com.orangelife.exception.AppBizException;
import com.orangelife.framework.toolkit.validate.ValidateUtil;
import com.orangelife.redis.core.redis.session.redisSession.WebServiceSession;
import com.orangelife.setting.constant.CodeConst;
import com.orangelife.setting.constant.InfoConst;
import com.orangelife.utils.StringUtils;

/**
 * service 基本类
 */
public abstract class BaseService extends AbstractV2TransferService {
	private static Validator validator;
	static {
		ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

		validator = factory.getValidator();
	}

	/**
	 * 验证全部需要有校验注解的字段
	 * 
	 * @param object
	 * @return
	 */
	public <T> Response validateObject(T object) {

		Set<ConstraintViolation<T>> constraintViolations = validator
				.validate(object);
		for (ConstraintViolation<T> constraintViolation : constraintViolations) {
			return getResponse(constraintViolation);
		}

		return null;
	}

	/**
	 * 验证指定一个有校验注解的字段
	 * 
	 * @param object
	 *            需要校验的对象
	 * @param property
	 *            需要校验对象里面字段
	 * @return
	 */
	public <T> Response validateProperty(T object, String property) {

		Set<ConstraintViolation<T>> constraintViolations = validator
				.validateProperty(object, property);
		for (ConstraintViolation<T> constraintViolation : constraintViolations) {

			return getResponse(constraintViolation);
		}

		return null;
	}

	/**
	 * 验证指定 有校验注解的不同字段列表
	 * 
	 * @param object
	 *            需要校验的对象
	 * @param properties
	 *            需要校验对象里面字段列表
	 * @return
	 */
	public <T> Response validateProperty(T object, List<String> properties) {
		Set<ConstraintViolation<T>> constraintViolations;
		for (String property : properties) {
			constraintViolations = validator.validateProperty(object, property);
			for (ConstraintViolation<T> constraintViolation : constraintViolations) {

				return getResponse(constraintViolation);
			}
		}
		return null;
	}

	private <T> Response getResponse(ConstraintViolation<T> constraintViolation) {
		Integer errCode;
		// String errInfo;
		StringBuilder errInfo = new StringBuilder();
		// 合成错误信息
		errInfo.append(constraintViolation.getPropertyPath())
				.append(constraintViolation.getMessage()).append(".  ")
				.append(constraintViolation.getInvalidValue());

		String simpleName = constraintViolation.getConstraintDescriptor()
				.getAnnotation().annotationType().getSimpleName();

		switch (simpleName) {
		case "NotBlank":
		case "NotNull":
		case "NotEmpty":
			errCode = 1001;// 不能为空。
			break;
		case "Length":
		case "Size":
			errCode = 1002;// 长度错误
			break;
		case "Pattern":
		case "Digits":
		case "Email":
		case "URL":
			errCode = 1003;// 格式错误
			break;
		case "Range":
			errCode = 1004;// 区分错误
			break;
		default:

			errCode = 98;// 其他未知的代码
			break;
		}
		// 打印日志
		logger.error(errInfo.toString().replaceAll("null", ""),
				constraintViolation.getPropertyPath());
		return this.abnormalResp(errCode,
				errInfo.toString().replaceAll("null", ""));
	}
	
	/**
	 * Id校验 校验通过返回null
	 * 
	 * @param id
	 *            需要校验的ID
	 * @param name
	 *            id的名称
	 * @return Response
	 */
	protected Response validateOrderID(String id, String name) {
		/* 订单ID */
		if (StringUtils.isBlank(id)) {
			logger.error(InfoConst.SYS_INFO_1001, name);
			return this.abnormalResp(CodeConst.SYS_CODE_1001, InfoConst.SYS_INFO_1001, name);
		}
		if (StringUtils.length(id) != 17) {
			logger.error(InfoConst.SYS_INFO_1002, name, id);
			return this.abnormalResp(CodeConst.SYS_CODE_1002, InfoConst.SYS_INFO_1002, name, id);
		}

		if (!StringUtils.isInt(id)) {
			logger.error(InfoConst.SYS_INFO_1003, name, id);
			return this.abnormalResp(CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003, name, id);
		}
		return null;
	}


	/**
	 * Id校验 校验通过返回null
	 * 
	 * @param id
	 *            需要校验的ID
	 * @param name
	 *            id的名称
	 * @return Response
	 */
	protected Response validateUUId(String id, String name) {
		/* ID非空 */
		if (StringUtils.isBlank(id)) {

			logger.error(InfoConst.SYS_INFO_1001, name, id);
			return this.abnormalResp(CodeConst.SYS_CODE_1001,
					InfoConst.SYS_INFO_1001, name, id);
		}

		/* ID长度错误的场合 */
		if (StringUtils.length(id) != 36) {
			logger.error(InfoConst.SYS_INFO_1002, name, id);
			return this.abnormalResp(CodeConst.SYS_CODE_1002,
					InfoConst.SYS_INFO_1002, name, id);
		}

		/* ID格式错误的场合 */
		if (!ValidateUtil.checkUUID(id)) {
			logger.error(InfoConst.SYS_INFO_1003, name, id);
			return this.abnormalResp(CodeConst.SYS_CODE_1003,
					InfoConst.SYS_INFO_1003, name, id);
		}

		return null;
	}
	
	/**
	 * 金额格式校验 校验通过返回null
	 * 
	 * @param param
	 *            需要校验的参数
	 * @param name
	 *            参数的名称
	 * @param length
	 *            长度，为0不校验
	 * @return Response
	 */
	protected Response validateMoney(String param, String name) {
		/* 非空 */
		if (StringUtils.isBlank(param)) {

			logger.error(InfoConst.SYS_INFO_1001, name, param);
			return this.abnormalResp(CodeConst.SYS_CODE_1001, InfoConst.SYS_INFO_1001, name, param);
		}

		/* 金额格式校验 */
		if (!StringUtils.isDoubleT(param)) {
			logger.error(InfoConst.SYS_INFO_1003, name, param);
			return this.abnormalResp(CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003, name, param);
		}

		return null;
	}

	/**
	 * 长度校验 校验通过返回null
	 * 
	 * @param param
	 *            需要校验的参数
	 * @param name
	 *            参数的名称
	 * @param length
	 *            长度，为0不校验
	 * @return Response
	 */
	protected Response validateLength(String param, String name, int length) {
		/* 非空 */
		if (StringUtils.isBlank(param)) {

			logger.error(InfoConst.SYS_INFO_1001, name, param);
			return this.abnormalResp(CodeConst.SYS_CODE_1001, InfoConst.SYS_INFO_1001, name, param);
		}

		/* 长度校验 */
		if (length > 0 && param.length() > length) {
			logger.error(InfoConst.SYS_INFO_1002, name, param);
			return this.abnormalResp(CodeConst.SYS_CODE_1002, InfoConst.SYS_INFO_1002, name, param);
		}

		return null;
	}

	/**
	 * 长度校验 校验通过返回null
	 * 
	 * @param param
	 *            需要校验的参数
	 * @param name
	 *            参数的名称
	 * @param length
	 *            长度，为0不校验
	 * @return Response
	 */
	protected Response validateLengthAndSpace(String param, String name, int length) {
		/* 非空 */
		if (StringUtils.isBlank(param)) {

			logger.error(InfoConst.SYS_INFO_1001, name, param);
			return this.abnormalResp(CodeConst.SYS_CODE_1001, InfoConst.SYS_INFO_1001, name, param);
		}

		/* 长度校验 */
		if (length > 0 && param.length() > length) {
			logger.error(InfoConst.SYS_INFO_1002, name, param);
			return this.abnormalResp(CodeConst.SYS_CODE_1002, InfoConst.SYS_INFO_1002, name, param);
		}

		/* 空格校验 */
		if (StringUtils.haveSpace(param)) {
			logger.error(InfoConst.SYS_INFO_1003, name, param);
			return this.abnormalResp(CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003, name, param);
		}

		return null;
	}

	/**
	 * 长度校验 校验通过返回null
	 * 
	 * @param param
	 *            需要校验的参数
	 * @param name
	 *            参数的名称
	 * @param length
	 *            长度，为0不校验
	 * @return Response
	 */
	protected Response validateLength(List<ValidateLength> list) {
		for (ValidateLength validateLength : list) {
			/* 非空 */
			if (StringUtils.isBlank(validateLength.getParam())) {

				logger.error(InfoConst.SYS_INFO_1001, validateLength.getName(), validateLength.getParam());
				return this.abnormalResp(CodeConst.SYS_CODE_1001, InfoConst.SYS_INFO_1001, validateLength.getName(), validateLength.getParam());
			}

			/* 长度校验 */
			if (validateLength.getLength() > 0 && validateLength.getParam().length() > validateLength.getLength()) {
				logger.error(InfoConst.SYS_INFO_1002, validateLength.getName(), validateLength.getParam());
				return this.abnormalResp(CodeConst.SYS_CODE_1002, InfoConst.SYS_INFO_1002, validateLength.getName(), validateLength.getParam());
			}
		}

		return null;
	}

	/**
	 * 时间校验 校验通过返回 null
	 * 
	 * @param time
	 *            需要校验的时间
	 * @param name
	 *            time的名称
	 * @return Response
	 */
	protected Response validateTimes(String time, String name) {
		/* ID非空 */
		// 非空
		if (StringUtils.isBlank(time)) {
			logger.error(InfoConst.SYS_INFO_1001, name);
			return this.abnormalResp(CodeConst.SYS_CODE_1001, InfoConst.SYS_INFO_1001, name);

		}

		if (!StringUtils.isInt(time)) {
			logger.error(InfoConst.SYS_INFO_1003, name);
			return this.abnormalResp(CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003, name, time);
		}

		if (time.length() > 13 || time.length() < 13) {
			logger.error(InfoConst.SYS_INFO_1002, name);
			return this.abnormalResp(CodeConst.SYS_CODE_1002, InfoConst.SYS_INFO_1002, name, time);
		}

		return null;
	}

	/**
	 * 区分校验 校验通过返回 null
	 * 
	 * @param type
	 *            需要校验的类型区分
	 * @param name
	 *            type的名称
	 * @param typeList
	 *            区分列表
	 * @return Response
	 */

	protected Response validateType(String type, String name, List<String> typeList) {

		// 非空
		if (StringUtils.isBlank(type)) {
			logger.error(InfoConst.SYS_INFO_1001, name);
			return this.abnormalResp(CodeConst.SYS_CODE_1001, InfoConst.SYS_INFO_1001, name);
		}
		if (!typeList.contains(type)) {
			logger.error(InfoConst.SYS_INFO_1004, name, type);
			return this.abnormalResp(CodeConst.SYS_CODE_1004, InfoConst.SYS_INFO_1004, name, type);
		}

		return null;
	}

	protected PageUtils validateLogin(HttpServletRequest servletRequest)
			throws AppBizException {
		PageUtils pageUtils = new PageUtils();

		/************************************************
		 * session 过期验证
		 ************************************************/
		WebServiceSession session = this.getWebServiceSession(servletRequest);
		if (session == null) {
			pageUtils.setResponse(this.abnormalResp(CodeConst.SYS_CODE_2001,
					InfoConst.SYS_INFO_2001));

			return pageUtils;
		}
		pageUtils.setBaseSession(session);
		return pageUtils;
	}

	/**
	 * 用于分页数值的检验与转换设置 当pageIndex,pageSize不为空时候进行数字类型格式校验,检验失败则设置错误信息的Reponse
	 * ,检验成功把Reponse设置null 通过则进行分页值设定,设置成功则返回;
	 * 并进行登陆权限校验,loginType访问资源权限:只能是web,app,null
	 * 
	 * @param servletRequest
	 * @param pageIndex
	 *            当前页数
	 * @param pageSize
	 *            每页总条数
	 * @param loginType
	 *            登陆类型
	 * @return
	 * @throws AppBizException
	 */
	protected PageUtils validatePageAndSetPage(
			HttpServletRequest servletRequest, String pageIndex, String pageSize)
			throws AppBizException {

		PageUtils pageUtils = new PageUtils();

		/************************************************
		 * session 过期验证
		 ************************************************/
		WebServiceSession session = this.getWebServiceSession(servletRequest);
		if (session == null) {
			pageUtils.setResponse(this.abnormalResp(CodeConst.SYS_CODE_2001,
					InfoConst.SYS_INFO_2001));
			return pageUtils;
		}
		pageUtils.setBaseSession(session);
		/************************************************
		 * 输入数据校验
		 ************************************************/
		/* 当前页数不为空的场合 */
		if (!StringUtils.isBlank(pageIndex)) {
			if (!ValidateUtil.isNumber(pageIndex)) {
				logger.error(InfoConst.SYS_INFO_1003, "当前页数", pageIndex);
				pageUtils.setResponse(this.abnormalResp(
						CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003,
						"当前页数", pageIndex));
				return pageUtils;
			}
		}

		/* 每页总条数不为空的场合 */
		if (!StringUtils.isBlank(pageSize)) {
			if (!ValidateUtil.isNumber(pageSize)) {
				logger.error(InfoConst.SYS_INFO_1003, "每页总条数", pageSize);
				pageUtils.setResponse(this.abnormalResp(
						CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003,
						"每页总条数", pageSize));
				return pageUtils;
			}
		}

		/* 当前页数值设定 */
		if (StringUtils.isBlank(pageIndex)) {

			pageUtils.setiPageIndex(1);
		} else {
			pageUtils.setiPageIndex(Integer.parseInt(pageIndex));
		}

		/* 每页总条数设定 */
		if (StringUtils.isBlank(pageSize)) {

			pageUtils.setiPageSize(200);
		} else {
			pageUtils.setiPageSize(Integer.parseInt(pageSize));
		}
		pageUtils.setResponse(null);
		return pageUtils;
	}

	/**
	 * 用于分页数值的检验与转换设置 ,当pageIndex,pageSize不为空时候进行数字类型格式校验,检验失败则设置错误信息的Reponse
	 * ,检验成功把Reponse设置null 通过则进行分页值设定,设置成功则返回;
	 * 
	 * @param servletRequest
	 * @param pageIndex
	 *            当前页数
	 * @param pageSize
	 *            每页总条数
	 * @param loginType
	 *            登陆类型
	 * @return
	 * @throws AppBizException
	 * 
	 */
	protected PageUtils validatePageAndSetPage(String pageIndex, String pageSize)
			throws AppBizException {

		PageUtils pageUtils = new PageUtils();
		/************************************************
		 * 输入数据校验
		 ************************************************/
		/* 当前页数不为空的场合 */
		if (!StringUtils.isBlank(pageIndex)) {
			if (!ValidateUtil.isNumber(pageIndex)) {
				logger.error(InfoConst.SYS_INFO_1003, "当前页数", pageIndex);
				pageUtils.setResponse(this.abnormalResp(
						CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003,
						"当前页数", pageIndex));
				return pageUtils;
			}
		}

		/* 每页总条数不为空的场合 */
		if (!StringUtils.isBlank(pageSize)) {
			if (!ValidateUtil.isNumber(pageSize)) {
				logger.error(InfoConst.SYS_INFO_1003, "每页总条数", pageSize);
				pageUtils.setResponse(this.abnormalResp(
						CodeConst.SYS_CODE_1003, InfoConst.SYS_INFO_1003,
						"每页总条数", pageSize));
				return pageUtils;
			}
		}

		/* 当前页数值设定 */
		if (StringUtils.isBlank(pageIndex)) {

			pageUtils.setiPageIndex(1);
		} else {
			pageUtils.setiPageIndex(Integer.parseInt(pageIndex));
		}

		/* 每页总条数设定 */
		if (StringUtils.isBlank(pageSize)) {

			pageUtils.setiPageSize(200);
		} else {
			pageUtils.setiPageSize(Integer.parseInt(pageSize));
		}
		pageUtils.setResponse(null);
		return pageUtils;
	}
	
	

}
